<?php
/**
 * 吉客云供应商订单SDK
 * @author hjj
 */
namespace App\Service\VendorClient\ShopjackyunApi;

use App\Service\Code\Normal;
use App\Service\BaseService;
use App\Model\PssModel\ServiceConfig;
use Service\AppService\IdService;
use App\Service\TaskServer\TaskWorker;

class ShopJackyunApiClient extends BaseService {
    //供应商编号
    const SUPPLIER_CODE = 'shopjackyun';
    //发货仓库编码 和  名称
    private $warehouse = [
        'BBC' => [
            'warehouseCode' => '04',//发货仓库编码
            'warehouseName' => '山东临沂保税仓',//仓库名称
        ],
        'GT' => [
            'warehouseCode' => '20',//发货仓库编码
            'warehouseName' => '深圳仓',//仓库名称
        ]
    ];
    private $config = [];

    public function __construct() {
        $this->config = config("api." . self::SUPPLIER_CODE);
    }

    /**
     * 创建订单
     * @param array $params
     * @param string $type BBC 保税订单 GT一般贸易订单
     * @return mixed
     */
    public function createOrder($param = [], $type = 'GT') {
        $orderInfo   = $param['supplierOrder'];
        $goodsList   = $param['orderGoods'];
        $order       = $param['order'];
        $binfo       = $param['binfo'];
        $companyInfo = $param['companyInfo'];
        $order_sn    = $orderInfo['supplier_dsn'];
        //支付流水号
        $pay_sn = $order['paySerial'] ?? $orderInfo['pay_sn'];
        //订单时间
        $order_time = $orderInfo['cd'] ? date('Y-m-d H:i:s', $orderInfo['cd']) : date('Y-m-d H:i:s', time());
        //支付时间
        $pay_time = isset($order['payTime']) && !empty($order['payTime']) ? date('Y-m-d H:i:s', $order['payTime']) : date('Y-m-d H:i:s', time());
        //运费
        $deliver_money = $orderInfo['deliver_money'] ?? 0.00;
        //下单支付的时候支付信息
        $apply_extends = @json_decode($orderInfo['apply_extends'], true);
        //判断支付方式是否存在
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $payCommanyCode = $order['payWay'] ?? $payCommanyCode;
        $payWayInfo     = ServiceConfig::instance()->getConfigByEventsValue(self::SUPPLIER_CODE, ServiceConfig::TYPE_PAY, $payCommanyCode);
        if (empty($payWayInfo)) {
            $payWayInfo = 6;//其它支付
        }
        //获取下单商品信息
        $palceOrderGoods = [];
        $goodsTotalMoney = 0;
        $way_tax_fee     = 0;
        foreach ($goodsList as $key => $item) {
            $tax_rate = bcadd('1', (string)$item['tax_rate'], 4);
            $price    = $item['price'];
            $spec_num = $item['spec_num'];
            $quantity = $item['quantity'];
            if( $key == 0 ) {
                $singleDeliveryMoney = bcdiv((string)$deliver_money,(string)$quantity,3);
                $singleDeliveryMoney = bcmul((string)$singleDeliveryMoney,(string)100,1);
                $singleDeliveryMoney = bcdiv((string)ceil($singleDeliveryMoney), (string)100,2);
                $price               = bcadd((string)$price, (string)$singleDeliveryMoney,2);
            }
            //单个商品的含税单价
            $singlePrice = bcdiv((string)$price, (string)$spec_num, 3);
            //单个商品的不含税单价
            $goodsPrice      = bcdiv((string)$price, (string)$tax_rate, 3);
            $goodsPrice      = bcdiv((string)$goodsPrice, (string)$spec_num, 3);
            $goodsPrice      = bcmul((string)$goodsPrice, (string)100, 1);
            $goodsPrice      = bcdiv((string)ceil($goodsPrice), 100, 2);
            $buyNum          = $spec_num * $quantity;
            $goodsTotalPrice = bcmul((string)$goodsPrice, (string)$buyNum, 2);
            //商品关税当前币种最小单位（分）
            $goodsCustomsTax = bcsub((string)$singlePrice, (string)$goodsPrice, 2);
            $taxAll          = bcmul((string)$goodsCustomsTax, (string)$buyNum, 2);
            //下单商品组
            $goodsInfo         = [
                'goodsNo'   => $item['supplier_skucode'],//商品编码
                'specName'  => $item['spec_name'],//规格名称
                'barcode'   => $item['barcode'],//条码
                'unit'      => $item['spec_name'],//单位
                'sellPrice' => $goodsPrice,//单价
                'sellCount' => $buyNum,//数量
                'sellTotal' => $goodsTotalPrice,//总金额,
                'taxFee'    => $goodsCustomsTax,//税金
            ];
            $palceOrderGoods[] = $goodsInfo;
            $goodsTotalMoney   = bcadd((string)$goodsTotalMoney, (string)$goodsTotalPrice, 2);
            $way_tax_fee       = bcadd((string)$way_tax_fee, (string)$taxAll, 2);
        }
        //订单总价（商品总额 + 税费 + 运费）
        $deliver_money = 0;
        $totalMoney    = bcadd((string)$goodsTotalMoney, (string)$deliver_money, 2);
        $totalMoney    = bcadd((string)$totalMoney, (string)$way_tax_fee, 2);
        //用户实际支付金额
        $real_total_money = $orderInfo['real_total_money'];
        //订单优惠金额
        $discount_money = bcsub((string)$totalMoney, (string)$real_total_money, 2);
        //推送数据
        $requestParam = [
            'tradeOrder' => [
                'tradeTime'         => $order_time,//下单时间
                'shopName'          => $this->config['SHOP_NAME'],//店铺名称、销售渠道
                'warehouseCode'     => $this->warehouse[$type]['warehouseCode'],//发货仓库编码
                'warehouseName'     => $this->warehouse[$type]['warehouseName'],//仓库名称
                'tradeType'         => 2,//订单类型(1=零售业务2=代发货3=预售订单5=代销售)
                'totalFee'          => $goodsTotalMoney,//商品金额
                'taxFee'            => $way_tax_fee,//税额
                'receivedPostFee'   => $deliver_money,//应收邮资
                'discountFee'       => $discount_money,//优惠金额
                'payment'           => $real_total_money,//应收金额
                'postFee'           => $deliver_money,//实际邮资
                'receiverName'      => $orderInfo['receive_name'],//收货人
                'phone'             => $orderInfo['recveive_phone'],//电话
                'mobile'            => $orderInfo['recveive_phone'],//手机
                'state'             => $orderInfo['province'],//省份
                'city'              => $orderInfo['city'],//城市
                'district'          => $orderInfo['district'],//地区
                'address'           => $orderInfo['receive_address'],//收货人详细地址
                'tradeOrderDetails' => $palceOrderGoods,//商品明细
                'payTime'           => $pay_time,//支付时间
                'payType'           => (int)$payWayInfo,//支付方式：1,支付宝 2,财付通 3,微信支付 4,银联支付 5,盛付通 6,其它 7,现金 8,储值卡 9,扫码付 10,挂账 11,诺诺支付 16,易付宝 32,有赞支付 33,汇付支付 35,商盟支付 36,易宝支付 37,汇聚支付 38,合利宝支付 27,通联支付
                'payNo'             => $order['paySerial'] ?? $apply_extends['paySerial'],//支付单号
                'accountName'       => $this->config['ACCOUNT_NAME'],//收款账户
                'onlineTradeNo'     => $orderInfo['order_sn'],//网点订单号
            ]
        ];
        // echo json_encode($requestParam, 320);die;
        $data = [
            'method' => 'createOrder',
            'data'   => $requestParam,
        ];
        $res  = $this->execute($data);
        if ($res['code'] == Normal::SUC) {
            return Normal::returnCode(Normal::SUC, "推送订单成功", [
                'thirdpart_order_sn' => $res['data']['result']['data']['tradeOrder']['tradeNo'],
            ]);
        }
        return $res;
    }

    /**
     * 取消订单
     * 仅[待审核]状态和预售订单可被取消
     * 接口创建的订单在吉克云的后台状态为：待审核
     * @param $data
     * @return array|string
     */
    public function cancelOrder($params = []) {
        $requestParam = [
            'cancelReason' => $params['order']['exceptReason'] ?? '取消订单',
            'tradeNos'     => $params['supplierOrder']['thirdpart_order_sn'],
        ];
        $data         = [
            'method' => 'cancelOrder',
            'data'   => $requestParam,
        ];
        $res          = $this->execute($data);
        if ($res['code'] == Normal::SUC) {
            return Normal::returnCode(Normal::SUC, $res['msg']);
        }
        return $res;
    }

    /**
     * 创建退换补发单
     * @param $data
     * @return array|string
     */
    public function afterSale($params = []) {
        $tradeNo   = $params['supplierOrder']['thirdpart_order_sn'];
        $goodsList = $params['orderGoods'];
        //获取下单商品信息
        $palceOrderGoods = [];
        foreach ($goodsList as $key => $item) {
            $tax_rate = bcadd('1', (string)$item['tax_rate'], 4);
            $price    = $item['price'];
            $spec_num = $item['spec_num'];
            $quantity = $item['quantity'];
            $buyNum   = $spec_num * $quantity;
            //单个商品的含税单价
            $singlePrice = bcdiv((string)$price, (string)$spec_num, 3);
            //单个商品的不含税单价
            $goodsPrice = bcdiv((string)$price, (string)$tax_rate, 3);
            $goodsPrice = bcdiv((string)$goodsPrice, (string)$spec_num, 3);
            $goodsPrice = bcmul((string)$goodsPrice, (string)100, 1);
            $goodsPrice = bcdiv((string)ceil($goodsPrice), 100, 2);
            //下单商品组
            $goodsInfo         = [
                'goodsNo'     => $item['supplier_skucode'],//商品编码
                'specName'    => $item['spec_name'],//规格名称
                'barcode'     => $item['barcode'],//条码
                // 'unit'        => $item['spec_name'],//单位
                'price'       => $goodsPrice,//单价
                'returnCount' => $buyNum,//退货数量
                'reasonDesc'  => $params['order']['exceptReason'] ?? '用户订单售后',//退换原因
            ];
            $palceOrderGoods[] = $goodsInfo;
        }
        //推送数据
        $requestParam = [
            'returnChange' => [
                'tradeNo'             => $tradeNo,//系统订单编号
                'shopName'            => $this->config['SHOP_NAME'],//店铺名称、销售渠道
                'reasonDesc'          => $params['order']['exceptReason'] ?? '用户订单售后',//退换原因
                'settlementType'      => 1,//结算类型(1先入库后结算 2先结算后入库)
                'resendType'          => 1,//补发类型(1先入库后补发 2先补发后入库)
                'refundTypeCode'      => 1,//结算方式(1网店平台退款2转账支付3转客户账户余额)
                'returnChangeDetails' => $palceOrderGoods//商品明细
            ]
        ];
        $data         = [
            'method' => 'afterSale',
            'data'   => $requestParam,
        ];
        $res          = $this->execute($data);
        if ($res['code'] == Normal::SUC) {
            return Normal::returnCode(Normal::SUC, $res['msg']);
        }
        return $res;
    }

    /**
     * 签名
     * @param $data
     * @return string
     */
    public function sign($data) {
        ksort($data);
        $strA = '';
        foreach ($data as $k => $v) {
            $strA .= "{$k}{$v}";
        }
        $strB = $this->config['APP_SECRET'] . $strA . $this->config['APP_SECRET'];
        return md5(strtolower($strB));
    }

    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute($param = []) {
        if (!isset($this->config['ACTION'][$param['method']]) || empty($this->config['ACTION'][$param['method']])) {
            return Normal::returnCode(Normal::FAIL, "请求路由未设置");
        }
        if (empty($param['data'])) {
            return Normal::returnCode(Normal::FAIL, "数据不能为空");
        }
        $url = $this->config['API_DOMAIN'];
        if (empty($url)) {
            return Normal::returnCode(Normal::FAIL, "接口地址不能为空");
        }
        $pushData         = [
            'method'      => $this->config['ACTION'][$param['method']],
            'appkey'      => $this->config['APP_KEY'],
            'version'     => $this->config['VERSION'],
            'contenttype' => $this->config['CONTENT_TYPE'],
            'timestamp'   => date('Y-m-d H:i:s'),
            'bizcontent'  => json_encode($param['data'], JSON_UNESCAPED_UNICODE),
        ];
        $pushData['sign'] = $this->sign($pushData);
        $parameter        = [
            [
                'tag'    => self::SUPPLIER_CODE . '_' . $param['method'],
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $url,
                'data'   => $pushData,
                'method' => 'post',
                'format' => 'form-data',
                'header' => [],
            ],
        ];
        $resTask          = TaskWorker::instance()->addTask($parameter);
        $resTask          = current($resTask);
        $result           = @json_decode($resTask['response']['result'], true);
        if (isset($result['code']) && $result['code'] == Normal::SUC) {
            return Normal::returnCode(Normal::SUC, "操作成功", $result);
        } else {
            $msg = $result['msg'] ?? '请求失败';
            return Normal::returnCode(Normal::FAIL, $msg);
        }
    }

    /**
     * 获取物流信息
     * @param array $param
     */
    public function queryOrderExpress( $params = [] )
    {
        $requestParam = [
            'tradeNo' => $params['thirdpart_order_sn'],
            'fields'  => "tradeNo,orderNo,shopName,companyName,warehouseName,logisticName,mainPostid,goodsDetail.goodsNo,flagNames,columnExt",
        ];
        $data = [
            'method' => 'queryOrder',
            'data'   => $requestParam,
        ];
        return $this->execute($data);
    }
}
